home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Tools 2
/
Amiga Tools 2.iso
/
grafik
/
bildanzeiger
/
seepix
/
source.lha
/
Palette.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-27
|
18KB
|
644 lines
/**Palette.c*************************************************************
* *
* SeePix -- by Hank Schafer *
* *
* SeePix is an IFF Picture Viewer. It works with Lo-Res, *
* Med-Res, Hi-Res, HAM, and EHB formats. I'm working on support *
* for X-Specs, and Anim5 formats. *
* *
* SeePix is based on a program by Olaf Barthel, called *
* 'LoadImage'. As released, LoadImage had a couple of bugs. *
* The Amiga-Key alternatives to menu use didn't all work. That's *
* been fixed. There were two separate print functions in LoadImage *
* which behaved exactly the same. The redundancy was eliminated. *
* LoadImage used the Topaz ROMFONT, and made no allowances for a *
* different system default font (under 2.04). I added a built-in *
* font. I've reworked the code considerably from the original *
* release, to allow for optimizations based on time and space. *
* *
* SeePix features a palette tool which allows "tweaking" of colors *
* prior to printing, allowing you to modify the color printout to *
* more closely resemble the original graphics (Blue is Blue, not *
* Purple). SeePix can be Iconified. SeePix features an ARP *
* interface. SeePix now uses the PathMaster File Selector. *
* *
************************************************************************
* *
* SeePix Copyright © 1992 by Hank Schafer; all rights reserved. *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 1, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to: *
* Free Software Foundation, Inc. *
* 675 Massachusetts Ave. *
* Cambridge MA 02139, USA *
* *
**************** Special Function Copyright Notices ********************
* *
****LoadImage Copyright Notice: *
* *
* LoadImage is © Copyright 1988, 1989, 1990 by MXM, all rights *
* reserved, written by Olaf Barthel. No guarantees of any kind are *
* made that this program is 100% reliable. Use this program on *
* your own risk! *
* *
****Iconify Copyright Notice: *
* *
* Copyright 1987 by Leo L. Schwab. *
* Permission is hereby granted for use in any and all programs, *
* both Public Domain and commercial in nature, provided this *
* Copyright notice is left intact. *
* *
****ColorWindow (Palette) Copyright Notice: *
* *
* ColorWindow Routine -- Color Window Routines *
* from Book 1 of the Amiga Programmers' Suite by RJ Mical *
* *
* Copyright (C) 1986, 1987, Robert J. Mical *
* All Rights Reserved. *
* *
****PathMaster Copyright Notice: *
* *
* -------------------------------------------------------------------- *
* Copyright © 1989 Justin V. McCormick. All Rights Reserved. *
* -------------------------------------------------------------------- *
* *
* The PathMaster name is a trademark of Justin V. McCormick. *
* *
* PathMaster File Selector source and documentation written by: *
* *
* Justin V. McCormick. *
* Copyright © 1989 by Justin V. McCormick. *
* All Rights Reserved. *
* *
* -------------------------------------------------------------------- *
************************************************************************
* *
* Hope this is something you can use and enjoy. *
* *
************************************************************************/
/*
* DoCWind(); and support functions - the palette requester
*/
extern struct Gadget ColorTemplateGadgets[COLOR_GADGETS_COUNT];
extern struct Image ColorPropsImages[3];
extern struct PropInfo ColorPropsInfos[3];
extern struct Image ColorRGBImage;
extern struct Image ColorHSLImage;
extern struct Image SuperColorImages[32];
extern UWORD RGBData[];
extern UWORD HSLData[];
UBYTE *AllocRemember();
struct IntuiMessage *GetMsg();
struct Window *OpenWindow();
/* ColorMode definitions */
#define COPYCOLOR 1
#define RANGE_FIRST 2
#define RANGE_SECOND 3
/* These are the dimensions of the color hit box */
#define COLOR_COLOR_ROWS (4 * 10)
#define COLOR_COLOR_COLS (8 * 15)
#define COLOR_COLOR_RIGHT (COLOR_BOX_LEFT + COLOR_COLOR_COLS - 1)
#define COLOR_COLOR_BOTTOM (COLOR_COLOR_TOP + COLOR_COLOR_ROWS - 1)
VOID ResetColorProps();
struct NewWindow ColorNewWindow =
{
20, 12, /* LeftEdge, TopEdge */
COLORWINDOW_WIDTH, COLORWINDOW_HEIGHT, /* Width, Height */
-1, -1, /* FrontPen, BackPen */
GADGETDOWN | GADGETUP | MOUSEBUTTONS | MENUPICK | MOUSEMOVE | ACTIVEWINDOW | INACTIVEWINDOW, /* IDCMP Flags */
WINDOWDRAG | SMART_REFRESH | NOCAREREFRESH | ACTIVATE, /* Flags */
&ColorTemplateGadgets[COLOR_GADGETS_COUNT - 1], /* First Gadget */
NULL, /* CheckMark */
(UBYTE *) "Print Palette:", /* Title */
NULL, /* Screen */
NULL, /* BitMap */
0, 0, /* Minimum Width & Height */
0, 0, /* Maximum Width & Height */
CUSTOMSCREEN, /* Type */
};
UWORD ColorMode;
UWORD RangeFirst;
struct Window *ColorWindow = NULL;
struct RastPort *ColorRPort;
struct ViewPort *ColorVPort;
WORD RowCount, RowHeight, ColumnCount, ColumnWidth;
UWORD SavePalette[32];
/* ======================================================================= */
/* === These Routines Open, Render, and Close the Color Window =========== */
/* ======================================================================= */
VOID
InitColorSizes(depth)
WORD depth;
/*
* This routine adjusts the row and column variables based on the number of
* colors supported by the ColorWindow's screen.
*/
{
RowCount = 1 << (depth >> 1);
RowHeight = COLOR_COLOR_ROWS / RowCount;
ColumnCount = 1 << ((depth + 1) >> 1);
ColumnWidth = COLOR_COLOR_COLS / ColumnCount;
}
VOID
DrawBox(rp, left, top, right, bottom)
struct RastPort *rp;
WORD left, top, right, bottom;
/* A quick utility routine */
{
WORD savepen;
savepen = ColorRPort->FgPen;
SetAPen(rp, 1);
SetDrMd(rp, JAM2);
Move(rp, left, top);
Draw(rp, left, bottom);
Draw(rp, right, bottom);
Draw(rp, right, top);
Draw(rp, left, top);
SetAPen(ColorRPort, savepen);
}
VOID
ColorRectFill(pen)
WORD pen;
/*
* This routine sets the pen in the RastPort as the current pen selected by
* the user, and then fills the color box with that pen color.
*/
{
SetAPen(ColorRPort, pen);
SetDrMd(ColorRPort, JAM1);
RectFill(ColorRPort, COLOR_BOX_LEFT, COLOR_BOX_TOP, COLOR_BOX_RIGHT, COLOR_BOX_BOTTOM);
}
VOID
DrawColorWindow()
/* This routine fills in all the graphic details of the ColorWindow */
{
WORD col, row, colstart, colend, rowstart;
WORD savepen;
savepen = ColorRPort->FgPen;
InitColorSizes(ColorRPort->BitMap->Depth);
ColorRectFill(ColorRPort->FgPen);
DrawBox(ColorRPort, COLOR_BOX_LEFT - 2, COLOR_BOX_TOP - 2, COLOR_BOX_RIGHT + 2, COLOR_BOX_BOTTOM + 2);
DrawBox(ColorRPort, COLOR_BOX_LEFT - 2, COLOR_COLOR_TOP - 2, COLOR_BOX_LEFT + (8 * 15) + 1, COLOR_COLOR_TOP + (4 * 10) + 1);
colstart = COLOR_BOX_LEFT;
colend = colstart + ColumnWidth - 1;
for (col = 0; col < ColumnCount; col++) {
rowstart = COLOR_COLOR_TOP;
for (row = 0; row < RowCount; row++) {
SetAPen(ColorRPort, (row * ColumnCount) + col);
RectFill(ColorRPort, colstart, rowstart, colend, rowstart + RowHeight - 1);
rowstart += RowHeight;
}
colstart += ColumnWidth;
colend += ColumnWidth;
}
SetAPen(ColorRPort, savepen);
}
struct Window *
OpenColorWindow(screen, firstpen)
struct Screen *screen;
WORD firstpen;
{
WORD i;
ColorNewWindow.Screen = screen;
ColorNewWindow.Type = CUSTOMSCREEN;
if ((ColorWindow = OpenWindow(&ColorNewWindow)) == 0)
return (NULL);
ColorVPort = &ColorWindow->WScreen->ViewPort;
ColorRPort = ColorWindow->RPort;
for (i = 0; i < 32; i++)
SavePalette[i] = GetRGB4(ColorVPort->ColorMap, i);
SetAPen(ColorRPort, firstpen);
ResetColorProps();
DrawColorWindow();
ColorMode = NULL;
return (ColorWindow);
}
VOID
CloseColorWindow(accept)
BOOL accept;
{
if (ColorWindow == NULL)
return;
if (NOT accept)
LoadRGB4(ColorVPort, &SavePalette[0], 32);
CloseWindow(ColorWindow);
ColorWindow = NULL;
}
/* ======================================================================= */
/* === These Routines Manage the User Interaction ======================== */
/* ======================================================================= */
BOOL
ColorGadgetGotten(gadget)
struct Gadget *gadget;
/*
* This routine manages the user's gadget selection. If one of the end
* gadgets, such as OK or CANCEL, was selected then this routine returns
* FALSE, else it returns TRUE.
*/
{
switch (gadget->GadgetID) {
case COLOR_OK:
CloseColorWindow(TRUE);
PrintPix();
return (FALSE);
break;
case COLOR_CANCEL:
CloseColorWindow(FALSE);
return (FALSE);
break;
case COLOR_COPY:
ColorMode = COPYCOLOR;
break;
case COLOR_RANGE:
ColorMode = RANGE_FIRST;
break;
case COLOR_HSL_RGB:
ResetColorProps();
break;
}
return (TRUE);
}
VOID
ColorRange(first, last)
WORD first, last;
/* Create the color range from first to last */
{
WORD i;
WORD whole, redfraction, greenfraction, bluefraction, divisor;
UWORD rgb;
WORD firstred, firstgreen, firstblue;
WORD lastred, lastgreen, lastblue;
WORD workred, workgreen, workblue;
/* If the pen numbers are out of order, swap */
if (first > last) {
i = first;
first = last;
last = i;
}
/*
* I need to see a spread of at least two, where there's at least one
* spot between the endpoints, else there's no work to do so I might as
* well just return now.
*/
if (first >= last - 1)
return;
rgb = GetRGB4(ColorVPort->ColorMap, first);
firstred = (rgb >> 8) & 0xF;
firstgreen = (rgb >> 4) & 0xF;
firstblue = (rgb >> 0) & 0xF;
rgb = GetRGB4(ColorVPort->ColorMap, last);
lastred = (rgb >> 8) & 0xF;
lastgreen = (rgb >> 4) & 0xF;
lastblue = (rgb >> 0) & 0xF;
divisor = last - first;
/*
* Do all math as fixed-point fractions where the low 8 bits are the
* fraction. This greatly lessens the effect of rounding errors.
*/
whole = (lastred - firstred) << 8;
redfraction = whole / divisor;
whole = (lastgreen - firstgreen) << 8;
greenfraction = whole / divisor;
whole = (lastblue - firstblue) << 8;
bluefraction = whole / divisor;
for (i = first + 1; i < last; i++) {
lastred = ((redfraction * (i - first)) + 0x0080) >> 8;
workred = firstred + lastred;
lastgreen = ((greenfraction * (i - first)) + 0x0080) >> 8;
workgreen = firstgreen + lastgreen;
lastblue = ((bluefraction * (i - first)) + 0x0080) >> 8;
workblue = firstblue + lastblue;
SetRGB4(ColorVPort, i, workred, workgreen, workblue);
}
}
VOID
ColorWindowHit(x, y)
WORD x, y;
/*
* The color boxes at the bottom-right of the ColorWindow are not gadgets.
* Instead, it's just graphics and this routine is used to detect whether the
* user has selected one of the color boxes.
*/
{
UWORD rgb, pen;
/* Have we got a color specifier? */
if ((x >= COLOR_BOX_LEFT) && (x <= COLOR_COLOR_RIGHT) && (y >= COLOR_COLOR_TOP) && (y <= COLOR_COLOR_BOTTOM)) {
/* Yes, it's one of the color boxes. Set this pen number */
x = x - COLOR_BOX_LEFT;
x = x / ColumnWidth;
y = y - COLOR_COLOR_TOP;
y = y / RowHeight;
pen = (y * ColumnCount) + x;
/* first, were we in COPY COLOR mode? */
if (ColorMode == COPYCOLOR) {
/* ok, copy old color here first! */
rgb = GetRGB4(ColorVPort->ColorMap, ColorRPort->FgPen);
SetRGB4(ColorVPort, pen, rgb >> 8, rgb >> 4, rgb);
ColorMode = NULL;
} else if (ColorMode == RANGE_FIRST) {
ColorMode = RANGE_SECOND;
RangeFirst = pen;
} else if (ColorMode == RANGE_SECOND) {
ColorMode = NULL;
ColorRange(RangeFirst, pen);
}
ColorRectFill(pen);
ResetColorProps();
}
}
VOID
SetPropValueGrunt(value, y)
WORD value, y;
{
UBYTE text[16];
if (value >= 0)
sprintf(&text[0], "%ld ", value);
else {
text[0] = ' ';
text[1] = ' ';
}
Move(ColorRPort, COLOR_VALUE_X, y);
Text(ColorRPort, &text[0], 2);
}
VOID
SetPropValues(red, green, blue)
WORD red, green, blue;
/* Sets the text to the right of the prop gadgets */
{
WORD savepen;
savepen = ColorRPort->FgPen;
SetAPen(ColorRPort, 1);
SetDrMd(ColorRPort, JAM2);
SetPropValueGrunt(red, COLOR_VALUE_REDY);
SetPropValueGrunt(green, COLOR_VALUE_GREENY);
SetPropValueGrunt(blue, COLOR_VALUE_BLUEY);
SetAPen(ColorRPort, savepen);
}
VOID
ModifyRGBColors()
{
UWORD newred, newgreen, newblue;
newred = ColorPropsInfos[0].HorizPot >> 12;
newgreen = ColorPropsInfos[1].HorizPot >> 12;
newblue = ColorPropsInfos[2].HorizPot >> 12;
SetRGB4(ColorVPort, ColorRPort->FgPen, newred, newgreen, newblue);
SetPropValues(newred, newgreen, newblue);
}
VOID
ModifyHSLColors()
{
UWORD rgb;
rgb = (UWORD) HSLToRGB(ColorPropsInfos[0].HorizPot, ColorPropsInfos[1].HorizPot, ColorPropsInfos[2].HorizPot);
SetRGB4(ColorVPort, ColorRPort->FgPen, rgb >> 8, rgb >> 4, rgb);
SetPropValues(-1, -1, -1);
}
VOID
ModifyColors()
/* This routine reacts to the user playing with one of the prop gadgets */
{
if (ColorTemplateGadgets[COLOR_HSL_RGB].Flags & SELECTED)
ModifyHSLColors();
else
ModifyRGBColors();
}
VOID
SetRGBProps(rgb)
UWORD rgb;
{
UWORD red, green, blue;
red = (rgb >> 8) & 0xF;
green = (rgb >> 4) & 0xF;
blue = (rgb >> 0) & 0xF;
ColorPropsInfos[0].HorizPot = (red << 12) | (red << 8) | (red << 4) | red;
ColorPropsInfos[1].HorizPot = (green << 12) | (green << 8) | (green << 4) | green;
ColorPropsInfos[2].HorizPot = (blue << 12) | (blue << 8) | (blue << 4) | blue;
SetPropValues(red, green, blue);
}
VOID
SetHSLProps(rgb)
UWORD rgb;
{
RGBToHSL(rgb, &ColorPropsInfos[0].HorizPot, &ColorPropsInfos[1].HorizPot, &ColorPropsInfos[2].HorizPot);
SetPropValues(-1, -1, -1);
}
VOID
ResetColorProps()
/*
* This routine resets the proportional gadgets according to the current pen
* number and the interaction technique
*/
{
WORD bluepos;
UWORD rgb;
rgb = GetRGB4(ColorVPort->ColorMap, ColorRPort->FgPen);
bluepos = RemoveGList(ColorWindow, &ColorTemplateGadgets[COLOR_BLUE], 3);
if (ColorTemplateGadgets[COLOR_HSL_RGB].Flags & SELECTED)
SetHSLProps(rgb);
else
SetRGBProps(rgb);
AddGList(ColorWindow, &ColorTemplateGadgets[COLOR_BLUE], bluepos, 3, 0);
RefreshGList(&ColorTemplateGadgets[COLOR_BLUE], ColorWindow, NULL, 3);
}
/* ======================================================================= */
/* === And finally, the Main Entry Point ================================= */
/* ======================================================================= */
BOOL
DoCWind(screen, left, top, firstpen, usergb)
struct Screen *screen;
WORD left, top, firstpen;
BOOL usergb;
{
struct IntuiMessage *message;
ULONG class;
struct Gadget *gadget;
BOOL mousemoved;
WORD x, y, code, i;
struct Remember *key;
UWORD *ptr;
BOOL retvalue;
key = NULL;
retvalue = FALSE;
if (ColorWindow)
goto DONE;
ColorNewWindow.LeftEdge = left;
ColorNewWindow.TopEdge = top;
if (usergb)
ColorTemplateGadgets[COLOR_HSL_RGB].Flags &= ~SELECTED;
else
ColorTemplateGadgets[COLOR_HSL_RGB].Flags |= SELECTED;
if ((ptr = (UWORD *) AllocRemember(&key, RGBHSL_SIZE * 2, MEMF_CHIP)) == NULL)
goto DONE;
ColorRGBImage.ImageData = ptr;
for (i = 0; i < RGBHSL_SIZE; i++)
*ptr++ = RGBData[i];
if ((ptr = (UWORD *) AllocRemember(&key, RGBHSL_SIZE * 2, MEMF_CHIP)) == NULL)
goto DONE;
ColorHSLImage.ImageData = ptr;
for (i = 0; i < RGBHSL_SIZE; i++)
*ptr++ = HSLData[i];
if (NOT OpenColorWindow(screen, firstpen & 0x3F))
goto DONE;
retvalue = TRUE;
FOREVER
{
Wait(1 << ColorWindow->UserPort->mp_SigBit);
mousemoved = FALSE;
while (message = GetMsg(ColorWindow->UserPort)) {
class = message->Class;
code = message->Code;
gadget = (struct Gadget *) (message->IAddress);
x = message->MouseX;
y = message->MouseY;
ReplyMsg(message);
switch (class) {
case GADGETDOWN:
case GADGETUP:
if (ColorGadgetGotten(gadget) == FALSE)
goto DONE;
break;
case MOUSEMOVE:
mousemoved = TRUE;
break;
case MOUSEBUTTONS:
if (code == SELECTDOWN)
ColorWindowHit(x, y);
break;
}
}
if (mousemoved)
ModifyColors();
SetPoint(ColorWindow);
}
DONE:
FreeRemember(&key, TRUE);
return (retvalue);
}